package top.huntwolf.admin.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.huntwolf.admin.common.enums.CodeMsg;
import top.huntwolf.admin.dao.CartDao;
import top.huntwolf.admin.dao.UserDao;
import top.huntwolf.admin.exception.ServiceException;
import top.huntwolf.admin.pojo.Cart;
import top.huntwolf.admin.pojo.User;
import top.huntwolf.admin.utils.UUIDUtil;
import top.huntwolf.admin.utils.WechatUtil;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Service
//@Transactional(timeout = 3)
public class UserService {

    @Autowired
    private UserDao userDao;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private CartDao cartDao;

    public User selectUserById(String open_id) {
        User user = userDao.selectUserById(open_id);
        if (user == null){
            throw new ServiceException(CodeMsg.USER_NOT_FOUND);
        }

        return user;
    }


    public int insertUser(User user) {
        return userDao.insert(user);
    }

    public HashMap<String,String> handleLogin(String code, String rawData, String signature, HttpServletRequest request) {
        // 用户非敏感信息：rawData
        // 签名：signature
        JSONObject rawDataJson = JSON.parseObject(rawData);
        // 1.接收小程序发送的code
        // 2.开发者服务器 登录凭证校验接口 appid + appsecret + code
        JSONObject sessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
        // 3.接收微信接口服务 获取返回的参数
        String openid = sessionKeyOpenId.getString("openid");

        String sessionKey = sessionKeyOpenId.getString("session_key");

        // 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
        String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);
        if (!signature.equals(signature2)) {
            throw new ServiceException(CodeMsg.SIGNATURE_ILLEGAL);
        }
        // 5.根据返回的User实体类，判断用户是否是新用户，是的话，将用户信息存到数据库；不是的话，更新最新登录时间
        User user = userDao.selectUserById(openid);

        if (user == null) {
            String nickName = rawDataJson.getString("nickName");
            String avatarUrl = rawDataJson.getString("avatarUrl");
            String gender = rawDataJson.getString("gender");
            String city = rawDataJson.getString("city");
            String country = rawDataJson.getString("country");
            String province = rawDataJson.getString("province");

            user = new User();
            user.setOpenId(openid);
            user.setCreateTime(new Date());
            user.setLastLogin(new Date());
            user.setSessionKey(sessionKey);
            user.setCity(city);
            user.setProvince(province);
            user.setCountry(country);
            user.setAvatar(avatarUrl);
            user.setGender(Integer.parseInt(gender));
            user.setNickname(nickName);
            //默认新用户登录角色为普通用户
            user.setRole("user");
            userDao.insert(user);
        } else {
            // 已存在，更新用户登录时间
            user.setLastLogin(new Date());
            userDao.update(user);
        }

        String token = tokenService.getToken(user);
        request.getSession().setAttribute("token",token);

        //返回前端数据：token + 用户角色
        HashMap<String, String> map = new HashMap<>();
        map.put("token",token);
        map.put("userRole",user.getRole());
        return map;
    }


    public PageInfo<User> selectAll(int pageNum, int pageSize){
        PageHelper.startPage(pageNum,pageSize);
        List<User> users = userDao.selectAll();
        PageInfo<User> pageInfo = new PageInfo<>(users);

        if (pageNum > pageInfo.getPages()){
            throw new ServiceException(CodeMsg.MAX_PAGES.fillArgs("没有更多内容"));
        }
        return pageInfo;
    }

    public void updateRole(User user){
        User userDB = userDao.selectUserById(user.getOpenId());
        if (userDB.getRole().equals(user.getRole())){
            throw new ServiceException(CodeMsg.ROLE_REPEAT.fillArgs(user.getRole()));
        }
        userDao.update(user);
    }

}
